home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 06 - 1990 / 06.09 Sep 90 / Debugger DA / Debugger.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-11-26  |  11.8 KB  |  436 lines  |  [TEXT/KAHL]

  1. /********************************************************************/
  2. /*                                                                    */
  3. /*    Source    - Debugger.c                                            */
  4. /*    Author    - Alexander S. Colwell, Copyright (C) 1988, 1989        */
  5. /*                                                                    */
  6. /*    Purpose   - This is the "Debugger" desk accessory interface        */
  7. /*                routines.                                            */
  8. /*                                                                    */
  9. /*    Routine   - DbgGetRefHdl: Setup debugging enviroment.            */
  10. /*                DbgPrint    : Do debugging print output.            */
  11. /*                DbgBufPrint : Do debugging buffer print output.        */
  12. /*                DbgDump        : Do debugging dump output.                */
  13. /*                DbgBufDump  : Do debugging buffer dump output.        */
  14. /*                DbgArgCnt    : Count # of arguments on the stack.    */
  15. /*                  DbgStrLen    : Do string length.                        */
  16. /*                                                                    */
  17. /*    Revisions - None.                                                */
  18. /*                                                                    */
  19. /********************************************************************/
  20.  
  21. #include    "Debugger.h"            /* Debugger defs                */
  22.  
  23.                                     /* Device control entry function*/
  24. #define    DbgDCtlEntry(refNbr) (UTableBase[-1*(refNbr + 1)])
  25.         
  26. short    DbgArgCnt();                /* Define forward references    */
  27.  
  28. DBGHDL    DbgGetRefHdl()
  29.  
  30.     {
  31.     
  32.         register DBGHDL    dbgHdl;        /* DA's reference # handle        */
  33.         
  34.         asm {                        /* Debugger's resource name        */
  35.                 
  36.                 CLR.L    -(sp)        ;Allocate return handle
  37.                 PEA        debuggerType;Load resource type
  38.                 PEA        @dbgRef        ;Load resource name 
  39.                 _GetNamedResource    ;Get resource handle
  40.                 MOVE.L    (sp)+,dbgHdl;Save resource handle
  41.                 BRA.S    @dbgExit    ;Skip around the resource name
  42.                 
  43. dbgRef: DC.B 18,'D','e','b','u','g','g','e','r',' ','R','e','f','e','r','e','n','c','e'
  44.                 
  45. dbgExit:
  46.  
  47.         }
  48.  
  49.         return(dbgHdl);                /* Return resource handle        */
  50.         
  51.     }
  52.     
  53. void    DbgPrint(dbgHdl,args)
  54.  
  55.     register DBGHDL    dbgHdl;            /* Working DA's ref # handle    */
  56.     char    *args;                    /* Input arguments                */
  57.     
  58.     {
  59.     
  60.         register short    refNbr;        /* Working DA's reference #        */
  61.         register short    daEnable;    /* Working save DA's enable state*/
  62.         register DCtlHandle dceHdl;    /* Working device control entry    */
  63.         
  64.         if (dbgHdl) {                /* Check if got the handle        */
  65.         
  66.             if (refNbr = (*dbgHdl)->daRefNbr) {/* Check if it's valid*/
  67.             
  68.                                     /* Check if got device ctrl hdl    */
  69.                 if (dceHdl = GetDCtlEntry(refNbr)) {
  70.                 
  71.                                     /* Save enabled stated            */
  72.                     daEnable = (*dceHdl)->dCtlFlags & dCtlEnable;
  73.                     
  74.                                     /* Enable DA's entry            */
  75.                     (*dceHdl)->dCtlFlags |= dCtlEnable;
  76.                     
  77.                     Control(refNbr,accDbgPrint,&args);/* Write it    */
  78.                     
  79.                     if (!daEnable)    /* Check if was not enabled        */
  80.                         (*dceHdl)->dCtlFlags &= ~dCtlEnable;
  81.                 
  82.                 }
  83.                 
  84.             }
  85.  
  86.         }
  87.         
  88.     }
  89.  
  90. void    DbgBufPrint(args)
  91.  
  92.     long    *args;                    /* Input arguments                */
  93.     
  94.     {
  95.     
  96.         register DBGHDL    dbgHdl;        /* Working DA's ref # handle    */
  97.         register DBGPTR    dbgPtr;        /* Working DA's ref handle        */
  98.         DCtlHandle         dceHdl;        /* Working device control entry    */
  99.         register char    *fmt;        /* Working format string        */
  100.         register char    *buf;        /* Working buffer address        */
  101.         long            *addr;        /* Working stack address        */
  102.         register long    fLen;        /* Working format string length    */
  103.         register long    dLen;        /* Working data buffer length    */
  104.         register long    argc;        /* Working # of argument bytes    */
  105.         register long    nextIdx;    /* Working next table index        */
  106.         register long    dataIdx;    /* Working data index            */
  107.         
  108.         dbgHdl = (DBGHDL)(&args[0]);/* Set debugger handle            */
  109.         
  110.         if (dbgHdl) {                /* Check if got the handle        */
  111.         
  112.             dbgPtr = *dbgHdl;        /* Setup debugger pointer        */
  113.             
  114.             if (dbgPtr->daRefNbr) {    /* Check if it's valid            */
  115.             
  116.                                     /* Check if got device ctrl hdl    */
  117.                 if (dceHdl = DbgDCtlEntry(dbgPtr->daRefNbr)) {
  118.                     
  119.                                     /* Check if have working buffers*/
  120.                     if (dbgPtr->bufTable && dbgPtr->bufData) {
  121.                 
  122.                                     /* Set next table index entry    */
  123.                         nextIdx = (dbgPtr->bufNextIdx + 1L) %
  124.                             dbgPtr->bufTableSize;
  125.  
  126.                                     /* Check if table over flow        */
  127.                         if (nextIdx == dbgPtr->bufTableIdx)
  128.                             dbgPtr->bufError = dbgTableOvrFlw;
  129.                             
  130.                         else {        /* Nope, continue                */
  131.                         
  132.                                     /* Get # of arguments            */
  133.                             argc = DbgArgCnt(&args) - 4L;
  134.                             
  135.                                     /* Check if has format string    */
  136.                             if (argc >= 4L) {
  137.                             
  138.                                     /* Set stack address            */
  139.                                 addr = (long *)(&args);
  140.                                 
  141.                                     /* Get variable argument        */
  142.                                 fmt = (char *)(addr[1]);
  143.                                 
  144.                                     /* Get format string length        */
  145.                                 fLen = DbgStrLen(fmt) + 1L;
  146.                                 
  147.                                     /* Check if it's even # of chars*/
  148.                                 if (fLen & 0x1L)    
  149.                                     fLen += 1L;/* Align it            */
  150.                                     
  151.                                     /* Computer total buffer length    */
  152.                                 dLen = argc + fLen + 2L;
  153.                                 
  154.                                     /* Check if time to buffer wrap    */
  155.                                 if ((dataIdx = dbgPtr->bufDataIdx) + dLen >= 
  156.                                     dbgPtr->bufDataSize) {
  157.                                     
  158.                                     /* Reset to beginning-of-buffer    */
  159.                                     dataIdx = 0L;
  160.                                 
  161.                                 }
  162.                                 
  163.                                     /* Check if buffer is to big    */
  164.                                 if (dLen > dbgPtr->bufDataSize)
  165.                                     dbgPtr->bufError = dbgBufOvrFlw;
  166.                                 
  167.                                     /* Check if there anything in buffer*/
  168.                                 else if (dbgPtr->bufTableIdx != 
  169.                                     dbgPtr->bufNextIdx) {
  170.                                     
  171.                                     /* Check if data buffer overflow*/
  172.                                     if (dataIdx <
  173.                                         (*dbgPtr->bufTable)[dbgPtr->bufTableIdx + 1L])
  174.                                         if (dLen + dataIdx >
  175.                                             (*dbgPtr->bufTable)[dbgPtr->bufTableIdx + 1L])
  176.                                             dbgPtr->bufError = dbgDataOvrFlw;
  177.                                             
  178.                                 }
  179.                                 
  180.                                     /* Check if there is no overflow*/
  181.                                 if (!dbgPtr->bufError) {
  182.                                 
  183.                                     /* Set next output line            */
  184.                                     dbgPtr->bufNextIdx = nextIdx;
  185.                                                          
  186.                                     /* Save data buffer index        */
  187.                                     (*dbgPtr->bufTable)[nextIdx] = 
  188.                                         dataIdx;
  189.                                         
  190.                                     /* Set buffer address            */
  191.                                     buf = &(*dbgPtr->bufData)[dataIdx];
  192.                                                 
  193.                                     *buf = accDbgPrint;/* Set code    */
  194.                                     
  195.                                     /* Copy the string format        */
  196.                                     BlockMove(fmt,buf + 2L,fLen);
  197.                                             
  198.                                     /* Copy the stack                */      
  199.                                     BlockMove(&addr[1],buf + fLen + 2L,argc);
  200.                                                   
  201.                                     /* Bump to next position        */
  202.                                     dbgPtr->bufDataIdx = dataIdx + dLen;
  203.                                     
  204.                                     /* Enable DA's entry            */
  205.                                     (*dceHdl)->dCtlFlags |= dNeedTime;
  206.                                     
  207.                                     /* Reset delay timer            */
  208.                                     (*dceHdl)->dCtlDelay = 1;
  209.                     
  210.                                 }
  211.                                 
  212.                             }
  213.                         
  214.                         }
  215.                         
  216.                     }
  217.                     
  218.                 }
  219.     
  220.             }
  221.         
  222.         }
  223.         
  224.     }
  225.     
  226. void    DbgDump(dbgHdl,buffer,size)
  227.  
  228.     register DBGHDL    dbgHdl;            /* Working DA's ref # handle    */
  229.     char    *buffer;                /* Input buffer                    */
  230.     long    size;                    /* Input buffer size            */
  231.     
  232.     {
  233.     
  234.         register short    refNbr;        /* Working DA's reference #        */
  235.         register short    daEnable;    /* Working save DA's enable state*/
  236.         register DCtlHandle dceHdl;    /* Working device control entry    */
  237.         long             csParam[2];    /* Working control param list    */
  238.         
  239.         if (dbgHdl) {                /* Check if got the handle        */
  240.         
  241.             if (refNbr = (*dbgHdl)->daRefNbr) {/* Check if it's valid*/
  242.             
  243.                                     /* Check if got device ctrl hdl    */
  244.                 if (dceHdl = GetDCtlEntry(refNbr)) {
  245.                 
  246.                                     /* Save enabled stated            */
  247.                     daEnable = (*dceHdl)->dCtlFlags & dCtlEnable;
  248.                     
  249.                                     /* Enable DA's entry            */
  250.                     (*dceHdl)->dCtlFlags |= dCtlEnable;
  251.                     
  252.                     csParam[0] = (long)(buffer);/* Init the param list*/
  253.                     csParam[1] = size;
  254.                 
  255.                                     /* OK, let's dump it now        */
  256.                     Control(refNbr,accDbgDump,csParam);
  257.                 
  258.                     if (!daEnable)    /* Check if was not enabled        */
  259.                         (*dceHdl)->dCtlFlags &= ~dCtlEnable;
  260.                 
  261.                 }
  262.                 
  263.             }
  264.             
  265.         }
  266.         
  267.     }
  268.  
  269. void    DbgBufDump(dbgHdl,buffer,size)
  270.  
  271.     register DBGHDL    dbgHdl;            /* Working DA's ref # handle    */
  272.     char    *buffer;                /* Input buffer                    */
  273.     long    size;                    /* Input buffer size            */
  274.     
  275.     {
  276.     
  277.         register DBGPTR    dbgPtr;        /* Working DA's ref handle        */
  278.         DCtlHandle         dceHdl;        /* Working device control entry    */
  279.         register char    *buf;        /* Working buffer address        */
  280.         register long    dLen;        /* Working data buffer length    */
  281.         register long    argc;        /* Working # of argument bytes    */
  282.         register long    nextIdx;    /* Working next table index        */
  283.         register long    dataIdx;    /* Working data index            */
  284.         
  285.         if (dbgHdl) {                /* Check if got the handle        */
  286.         
  287.             dbgPtr = *dbgHdl;        /* Setup debugger pointer        */
  288.             
  289.             if (dbgPtr->daRefNbr) {/* Check if it's valid            */
  290.             
  291.                                     /* Check if got device ctrl hdl    */
  292.                 if (dceHdl = DbgDCtlEntry(dbgPtr->daRefNbr)) {
  293.                     
  294.                                     /* Check if have working buffers*/
  295.                     if (dbgPtr->bufTable && dbgPtr->bufData) {
  296.                 
  297.                                     /* Set next table index entry    */
  298.                         nextIdx = (dbgPtr->bufNextIdx + 1L) %
  299.                             dbgPtr->bufTableSize;
  300.  
  301.                                     /* Check if table over flow        */
  302.                         if (nextIdx == dbgPtr->bufTableIdx)
  303.                             dbgPtr->bufError = dbgTableOvrFlw;
  304.                             
  305.                         else {        /* Nope, continue                */
  306.                         
  307.                                     /* Computer total buffer length    */
  308.                             dLen = size + sizeof(size) + 2L;
  309.                             
  310.                             if (dLen & 0x1L)/* Check if odd size    */
  311.                                 dLen += 1L;/* Let's make it even    */
  312.                             
  313.                                     /* Check if time to buffer wrap    */
  314.                             if ((dataIdx = dbgPtr->bufDataIdx) + dLen >= 
  315.                                 dbgPtr->bufDataSize) {
  316.                                 
  317.                                     /* Reset to beginning-of-buffer    */
  318.                                 dataIdx = 0L;
  319.                             
  320.                             }
  321.                             
  322.                                     /* Check if buffer is to big    */
  323.                             if (dLen > dbgPtr->bufDataSize)
  324.                                 dbgPtr->bufError = dbgBufOvrFlw;
  325.                                 
  326.                                     /* Check if there anything in buffer*/
  327.                             else if (dbgPtr->bufTableIdx != 
  328.                                 dbgPtr->bufNextIdx) {
  329.                                 
  330.                                     /* Check if data buffer overflow*/
  331.                                 if (dataIdx <
  332.                                     (*dbgPtr->bufTable)[dbgPtr->bufTableIdx + 1L])
  333.                                     if (dLen + dataIdx >
  334.                                         (*dbgPtr->bufTable)[dbgPtr->bufTableIdx + 1L])
  335.                                         dbgPtr->bufError = dbgDataOvrFlw;
  336.                                     
  337.                             }
  338.                             
  339.                                     /* Check if there is no overflow*/
  340.                             if (!dbgPtr->bufError) {
  341.                             
  342.                                     /* Set next output line            */
  343.                                 dbgPtr->bufNextIdx = nextIdx;
  344.                                                      
  345.                                     /* Save data buffer index        */
  346.                                 (*dbgPtr->bufTable)[nextIdx] = 
  347.                                     dataIdx;
  348.                                     
  349.                                     /* Set buffer address            */
  350.                                 buf = &(*dbgPtr->bufData)[dataIdx];
  351.                                               
  352.                                 *buf = accDbgDump;/* Set code        */
  353.                                 
  354.                                     /* Copy the size of the buffer    */
  355.                                 BlockMove(&size,buf + 2L,
  356.                                     (long)(sizeof(size)));
  357.                                         
  358.                                     /* Copy the buffer                */      
  359.                                 BlockMove(buffer,
  360.                                     buf + sizeof(size) + 2L,size);
  361.                                               
  362.                                     /* Bump to next position        */
  363.                                 dbgPtr->bufDataIdx = dataIdx + dLen;
  364.                                 
  365.                                     /* Enable DA's entry            */
  366.                                 (*dceHdl)->dCtlFlags |= dNeedTime;
  367.                                 
  368.                                     /* Reset delay timer            */
  369.                                 (*dceHdl)->dCtlDelay = 1;
  370.                 
  371.                             }
  372.                                 
  373.                         }
  374.                         
  375.                     }
  376.                     
  377.                 }
  378.     
  379.             }
  380.         
  381.         }
  382.                 
  383.     }
  384.  
  385. short    DbgArgCnt(vararg)
  386.  
  387.    long    vararg;                        /* Variable argument list        */
  388.    
  389.    {
  390.    
  391.       register union {                /* Union of three variable types*/
  392.         long             addr;        /* Address of the types            */
  393.         long             **args;
  394.         }                varg;        /* Working variable argument list*/
  395.       register unsigned long instr;    /* Working instruction            */
  396.       register long        arg;        /* Working argument                */
  397.       register long        count = 0L;    /* # of arguments                */
  398.  
  399.       varg.addr = vararg;            /* Init variable argument list    */
  400.       
  401.       varg.addr -= 4;                /* Position to the instruction    */
  402.       
  403.       instr = **varg.args & 0xffff0000;/* Set instruction word        */
  404.       
  405.       if (instr == 0x4fef0000)        /* Check if ADD instruction        */
  406.          count = (**varg.args & 0x0000ffff );/* Set # of bytes        */
  407.      
  408.                                      /* Check if ADDI instruction    */
  409.       else if ((instr & 0xf1ff0000) == 0x508f0000) {
  410.       
  411.                                       /* Check if zero, then 8 bytes    */
  412.          if (!(count = ((instr & 0x0e000000) >> 25)))
  413.             count = 8;                /* Reset to eight bytes on stack*/
  414.             
  415.       }
  416.       
  417.       return(count);                /* Return count                    */
  418.       
  419.    }
  420.  
  421. long    DbgStrLen(s)
  422.  
  423.     register char    *s;                /* String pointer                */
  424.     
  425.     {
  426.     
  427.         register long    sLen = 0;    /* String length                */
  428.         
  429.         while(*s++)                    /* Continue till end-of-string    */
  430.             sLen++;                    /* Bump string length            */
  431.             
  432.         return(sLen);                /* Return string length            */
  433.         
  434.     }
  435.     
  436.